package com.axonactive.yolo.service.internal;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.List;
import java.util.Iterator;

import javax.servlet.http.HttpServletRequest;

import org.apache.log4j.Logger;

import com.axonactive.yolo.dto.Flight;
import com.axonactive.yolo.dtotemp.WegoFlight;
import com.axonactive.yolo.util.CONSTANTS;
import com.axonactive.yolo.util.IOUtil;
import com.axonactive.yolo.util.Utils;

/**
 * The base class used for set parameters for flight requesting, you must implement the abstract methods: sendRequest and processReponse. 
 * @author pqtrung
 *
 */
public abstract class FlightRequester {
	protected String departureAirportCode;
	protected String arrivalAirportCode;
	protected String tripType = "roundTrip";
	protected String cabinClass = CONSTANTS.CABIN_ECONOMY_0;
	protected String inboundDate;
	protected String outboundDate;
	protected String numAdults = "1";
	protected String numChildren = "0";
	protected String numInfants = "0";
	protected String rangeValue = "0";
	protected String currencyCode = CONSTANTS.USD;
	private static final Logger LOGGER = Logger.getLogger(FlightRequester.class);

	/***
	 * 
	 * @param response response you got from the server
	 * @return list of flights.
	 */
	public abstract List<Flight> processResponse(String response);
	
	/***
	 * This method is used for only getting data from Wego. WegoFlight DTO is temporary. In almost of other cases, you should avoid use them.
	 * Use processResponse to return list of Flight (in package com.axonactive.domain)
	 *  
	 * @param response response response you got from the server
	 * @return list of WegoFlight objects
	 */
	public abstract List<WegoFlight> processResponseWego(String response);

	/***
	 * This method is called after run setRequest method. It will send the request with set of parameters to server.
	 * @return response in String format
	 */
	public abstract String sendRequest();

	/***
	 * This method is used for set parameters for a  flight requesting 
	 * @param departureAirportCode required - 3-letter IATA airport code (e.g. SIN)
	 * @param arrivalAirportCode required - 3-letter IATA airport code (e.g. BKK)
	 * @param tripType required - Possible Values: oneWay, roundTrip, default is roundTrip
	 * @param cabinClass  required - Possible Values: Economy, Business, First, default is Economy
	 * @param inboundDate yyyy-MM-dd (not required for oneWay flights)
	 * @param outboundDate required - yyyy-MM-dd
	 * @param numAdults required - 1- 9: default is 1
	 * @param numChildren required - 0- 6: default is 0
	 * @param numInfants required - 0- 6: default is 0
	 * @param rangeValue 0 if departure/returns dates are exact or 1 for flexible dates (+/-3 days)
	 * @param currencyCode the code of the current currency
	 */
	public void setRequest(String departureAirportCode,
			   String arrivalAirportCode, String tripType, String cabinClass,
			   String inboundDate, String outboundDate, String numAdults,
			   String numChildren, String numInfants, String rangeValue,String currencyCode) {
		this.departureAirportCode = departureAirportCode;
		this.arrivalAirportCode = arrivalAirportCode;
		this.tripType = inboundDate.equals("") ? "oneWay" : "roundTrip";
		this.cabinClass = cabinClass.equals("") ? this.cabinClass : cabinClass;
		this.inboundDate = inboundDate;
		this.outboundDate = outboundDate;
		this.numAdults = numAdults.equals("") ? this.numAdults : numAdults;
		this.numChildren = numChildren.equals("") ? this.numChildren : numChildren;
		this.numInfants = numInfants.equals("") ? this.numInfants : numInfants;
		this.rangeValue = rangeValue.equals("") ? this.rangeValue : rangeValue;
		this.currencyCode = currencyCode.equals("") ? this.currencyCode : currencyCode;
	}

	private static String call(String url) throws IOException {
		URL requestUrl = new URL(url);
		URLConnection con = requestUrl.openConnection();
		BufferedReader rd = new BufferedReader(new InputStreamReader(
				con.getInputStream()));
		StringBuilder sb = new StringBuilder();
		int cp;
		try {
			while ((cp = rd.read()) != -1) {
				sb.append((char) cp);
			}
		} catch (Exception e) {
			LOGGER.info("Error",e);
		}
		String json = sb.toString();
		LOGGER.info("Response from wego: " + json);
		return json;
	}

	public String sendRequestToMockDB(HttpServletRequest httpRequest) throws Exception {
//		System.setProperty("webdriver.chrome.driver",
//				"driver\\chromedriver.exe");
//		WebDriver driver = new HtmlUnitDriver(true);
		String serverURL = Utils.getURLWithContextPath(httpRequest);
//		serverURL=serverURL.substring(6);
//		serverURL="http:"+serverURL;
		String start_search = serverURL+"/API.html?"
				+ "departureAirportCode="
				+ this.departureAirportCode
				+ "&arrivalAirportCode="
				+ this.arrivalAirportCode
				+ "&tripType="
				+ this.tripType
				+ "&cabinClass="
				+ this.cabinClass
				+ "+&outboundDate="
				+ this.outboundDate
				+ "&numAdults="
				+ this.numAdults
				+ "&numChildren="
				+ this.numChildren
				+ "&numInfants="
				+ this.numInfants
				+ "&rangeValue="
				+ this.rangeValue;
		if (this.inboundDate != "") {
			start_search += "&inboundDate=" + this.inboundDate;
		}
		//String parametes=this.departureAirportCode+CONSTANTS.DELIMITER+this.arrivalAirportCode+CONSTANTS.DELIMITER+this.tripType+CONSTANTS.DELIMITER+this.cabinClass+CONSTANTS.DELIMITER+this.outboundDate+CONSTANTS.DELIMITER+this.inboundDate+CONSTANTS.DELIMITER+this.numAdults+CONSTANTS.DELIMITER+this.numChildren+CONSTANTS.DELIMITER+this.numInfants+CONSTANTS.DELIMITER+this.rangeValue;
		//LOGGER.info("parameters: "+parametes);
		//LOGGER.info("start search: "+start_search);		
//		driver.get(start_search);
//		String source=driver.findElement(By.tagName("body")).getText();
//		LOGGER.info("Requester Tracking - sendRequestToMockDB- get response:\n"+source);
//		LOGGER.info("\n----------------------------------------------------\n");
		String source=call(start_search);
		//List<String> sources=IOUtil.executeProgram("E:\\MockDB.jar trung binh");
		
		return source;
	}
	public static String executeJarFile(String parameters)
	{
//		String paramters="HAN/SGN/roundTrip/Economy/2014-06-20/2014-06-25/1/0/0/0";
		List<String> ls=IOUtil.executeProgram(CONSTANTS.MOCKDB+parameters);
		String result="";
		for (Iterator<String> iterator = ls.iterator(); iterator.hasNext();) {
			String string = (String) iterator.next();
//			Logger.getLogger(FlightRequester.class).info(string);
			result+=string;
		}
		return result;
	}


}
